package com.jumei.flume.common;

import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 提供共用的方法等
 */
public class CommonUtils {
    private static final Logger LOGGER = LoggerFactory.getLogger(CommonUtils.class);
    public final static DateTimeFormatter logDateTimeFmt = DateTimeFormat.forPattern("dd/MMM/yyyy:HH:mm:ss").withLocale(Locale.US);
    public final static DateTimeFormatter dateTimeFmt = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss").withLocale(Locale.US);

    /**
     * 把特殊符号替换为空字符串
     *
     * @param str
     * @param symbols
     * @return
     */
    public static String removeSpecialSymbol(String str, String... symbols) {
        String result = str;
        for (String symbol : symbols) {
            result = result.replaceAll(symbol, "");
        }
        return result;
    }

    /**
     * 使用分隔符||来连接传递进来的参数项，生成一行基于||分隔各信息字段的一行数据(字符串)
     *
     * @param str
     * @return
     */
    public static String createNewKey(String... str) {
        StringBuilder key = new StringBuilder();
        for (String s : str) {
            key.append(s.replace("||", "")).append("||");
        }
        key = key.delete(key.length() - 2, key.length());
        return key.toString().replaceAll("\n", "").replaceAll("\r", "");
    }

    /**
     * 使用hive表默认分割符，来生成一行新的记录
     *
     * @param str
     * @return
     */
    public static String createHiveKey(String... str) {
        StringBuilder key = new StringBuilder();
        Integer length = str.length;
        int count = 0;
        for (String s : str) {
            if (s == null) {
                s = "";
            }
            key.append(s.replace("\001", ""));
            count++;
            if (count < length) {
                key.append("\001");
            }
        }
        return key.toString().replaceAll("\n", "").replaceAll("\r", "");
    }

    /**
     * 对 字符串 进行解码
     *
     * @param source
     * @return
     */
    public static String getDecodeFiled(String source) {
        String des = "";
        try {
            des = URLDecoder.decode(source, "UTF-8");
        } catch (Exception e) {
            des = source;
        }
        return des;
    }

    /**
     * 正则匹配 返回group(index)
     *
     * @param patterRegx
     * @param data
     * @return
     */
    public static String getValue(String patterRegx, String data, Integer index) {
        Pattern pattern = Pattern.compile(patterRegx);
        Matcher matcher = pattern.matcher(data);
        String value = "";
        if (matcher.find()) {
            value = getDecodeFiled(matcher.group(index));
        }
        if (value != null) {
            value = value.replaceAll("\n", "");
        }
        return value;
    }

    /**
     * 解析nginx日志中的cookie字符串，提取出cookie中的每个参数
     *
     * @param cookie
     * @return
     */
    public static Map<String, String> analysisCookie(String cookie) {
        String[] params = cookie.split("\\;", -1);
        Map<String, String> map = new HashMap<String, String>();
        for (String param : params) {
            try {
                int index = param.indexOf("=");
                if (index == -1) {
                    continue;
                }
                String key = param.substring(0, index).trim();
                String value = param.substring(index + 1).trim();
                map.put(key, CommonUtils.getDecodeFiled(value));
            } catch (Exception e) {
                LOGGER.error("解析cookie异常 : " + param);
            }
        }
        return map;
    }

    /**
     * 解析nginx日志中的url参数，提取出url中的每个参数
     *
     * @param paramStr
     * @return
     */
    public static Map<String, String> analysisUrlParam2Map(String paramStr) {
        String[] params = paramStr.split("&", -1);
        Map<String, String> map = new HashMap<String, String>();
        for (String param : params) {
            try {
                int index = param.indexOf("=");
                String key = param.substring(0, index).trim();
                String value = param.substring(index + 1).trim();
                map.put(key, CommonUtils.getDecodeFiled(value));
            } catch (Exception e) {
                LOGGER.info("解析url参数异常 : " + param);
            }
        }
        return map;
    }

    public static Map<String, String> analysisRequest(String request) {
        String[] infos = request.split("\\?", -1);
        Map<String, String> map = new HashMap<String, String>();
        if (infos.length > 1) {
            String[] params = infos[1].split("&", -1);
            for (String param : params) {
                try {
                    int index = param.indexOf("=");
                    String key = param.substring(0, index).trim();
                    String value = param.substring(index + 1).trim();
                    map.put(key, CommonUtils.getDecodeFiled(value));
                } catch (Exception e) {
                    LOGGER.info("解析request参数异常 : " + param);
                }
            }
        }

        return map;
    }


    /**
     * 从 cookieMap 中获取 key 的 value
     *
     * @param key
     * @param map
     * @return
     */
    public static String getMapValue(String key, Map<String, String> map) {
        String value = "";
        if (map.containsKey(key)) {
            value = map.get(key);
        }
        value = getDecodeFiled(value);
        return value;
    }

    /**
     * 从 utma 解析出 userId，以点为分割符，取第2个和第3个连接起来做为userId
     *
     * @param utma
     * @return
     */
    public static String getUtmaUserId(String utma) {
        String[] arr = utma.split("\\.", -1);
        String ga_user_id = "";
        if (arr.length > 2) {
            ga_user_id = arr[1] + arr[2];
        }
        return ga_user_id;
    }

    /**
     * 解析nginx日志 url 与 methhod
     *
     * @param secondInfo
     * @return
     */
    public static String[] getUrl(String secondInfo) {
        String method = "";
        String url = "";
        if (StringUtils.isNotBlank(secondInfo) && secondInfo.indexOf("POST") != -1) {
            method = "POST";
            url = secondInfo.substring(5);
            int lastHttpIndex = url.lastIndexOf(" HTTP/");
            if (lastHttpIndex != -1) {
                url = url.substring(0, lastHttpIndex);
            }
        } else if (StringUtils.isNotBlank(secondInfo) && secondInfo.indexOf("GET") != -1) {
            method = "GET";
            url = secondInfo.substring(4);
            int lastHttpIndex = url.lastIndexOf(" HTTP/");
            if (lastHttpIndex != -1) {
                url = url.substring(0, lastHttpIndex);
            }
        } else {
            url = secondInfo;
        }
        return new String[]{method, url};
    }

    /**
     * 解析nginx日志时间
     *
     * @param date
     * @return
     */
    public static DateTime getCreateTime(String date) {
        DateTime dateTime = null;
        if (StringUtils.isNotBlank(date)) {
            date = date.replace("[", "").replace("]", "");

            dateTime = DateTime.parse(date, CommonUtils.logDateTimeFmt);
        }
        return dateTime;
    }

    //转换为DateTime对象
    public static DateTime objToDateTime(Object obj) {
        DateTime dateTime = null;
        try {
            dateTime = DateUtil.getDateTime((String) obj, "yyyy-MM-dd HH:mm:ss");
        } catch (Exception e) {
            LOGGER.error("时间转换错误", e);
        }
        return dateTime;
    }

    //转换为int类型
    public static Integer objToInt(Object obj) {
        Integer num = 0;
        try {
            num = Integer.parseInt((String) obj);
        } catch (Exception e) {
            LOGGER.error("string转换int错误", e);
        }
        return num;
    }

    //转换为String类型
    public static String objToStr(Object obj) {
        String str = "";
        try {
            if (obj == null) {
                return str;
            }
            String type = obj.getClass().getSimpleName();
            if ("Integer".equals(type)) {
                str = String.valueOf((Integer) obj);
            } else if ("Float".equals(type)) {
                str = String.valueOf((Float) obj);
            } else if ("Double".equals(type)) {
                str = String.valueOf((Double) obj);
            } else if ("Long".equals(type)) {
                str = String.valueOf((Long) obj);
            } else {
                str = String.valueOf(obj);
            }
        } catch (Exception e) {
            LOGGER.error("obj to str 异常", e);
        }
        return str;
    }

    public static String mapToString(Map<String, Object> map, String[] mapColumns, String connector) {
        StringBuilder stringBuilder = new StringBuilder();
        try {
            if (map == null) {
                return "";
            }
            for (String column : mapColumns) {
                String value = objToStr(map.get(column)).replaceAll(connector, "").replaceAll("\n", "").replaceAll("\r", "");
                stringBuilder.append(value).append(connector);
            }
        } catch (Exception e) {
            LOGGER.error("解析错误", e);
        }
        if (stringBuilder.length() > 0) {
            return stringBuilder.substring(0, stringBuilder.length() - connector.length());
        }
        return "";
    }


    public static String newLine(String decollator, String... str) {
        StringBuilder key = new StringBuilder();
        for (String s : str) {
            key.append(s.replace(decollator, "")).append(decollator);
        }
        key = key.delete(key.length() - decollator.length(), key.length());
        return key.toString().replaceAll("\n", "").replaceAll("\r", "");
    }

    /**
     * 通过utma计算user
     *
     * @param utma
     * @return
     */
    public String getUserFromUtma(String utma) {
        String[] datas = utma.split("\\.", -1);
        if (datas != null && datas.length >= 3) {
            StringBuffer user = new StringBuffer();
            user.append(datas[1]);
            user.append(datas[2]);
            return user.toString();
        }
        return "";
    }

}
